/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package utp.tepc.padroes.projeto.observer;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * 
 * @author Diego
 */
public class Reator implements Subject
{
    private List<Observer> monitores = new ArrayList<Observer>();
    private float temperatura;
    private float pressao;

    private float otimoPressao;
    private float maxTemp;
    private float minTemp;

    private String nome;
    private Boolean isRun;
    
    private int holdStill = 0;

    public Boolean getIsRun()
    {
        return isRun;
    }

    public Reator(float otimoPressao, float maxT, float minT, String nome)
    {
	this.otimoPressao = otimoPressao;
	this.maxTemp = maxT;
	this.minTemp = minT;
	this.nome = nome;
	this.isRun = true;
    }

    // public String getNome()
    // {
    // return this.nome;
    // }

    public void iniciarOperacao()
    {
	temperatura = simularTemperatura();
	pressao = simularPressao();
	
	System.out.println(nome + " - " + temperatura + " - " + pressao);

	int p = this.runPressao();
	int t = this.runTemperatura();
	
	if(p > t)
	    this.holdStill = p;
	else
	    this.holdStill = t;
	
	if(holdStill > 0)
	    notificar(this.nome + "Equalizando "+ this.holdStill + " ....................");
    }

    public void equalizar()
    {
	if(holdStill > 0)
	    holdStill--;
	else
	    isRun = true;
    }
    
    private int runPressao()
    {
	float variacaoP;
	variacaoP = verificarPressao();
	
	if(variacaoP > 0)
	    isRun = false;
	
	if (variacaoP > 0 && variacaoP <= 1)
	{
	    return 2;
	    //notificar(this.nome + ": Equalizando Pressão por 2 turnos.");
	    //this.holdStill = 2;
	}
	else if (variacaoP > 1)
	{
	    return 4;
	    //notificar(this.nome + ": Equalizando Pressão por 4 turnos.");
	    //this.holdStill = 4;
	}
	else
	{
	    return 0;
	    //notificar(this.nome + ": Funcionando normalmente.");
	    //this.holdStill = 0;
	}
    }

    private int runTemperatura()
    {
	float variacaoT;
	variacaoT = verificarTemperatura();
	
	if(variacaoT > 0)
	    this.isRun = false;

	if (variacaoT > 0 && variacaoT <= 5)
	{
//	    notificar(this.nome + ": Equalizando Temperatura por 1 turno.");
//	    this.holdStill = 1;
	    return 1;
	}
	else if (variacaoT > 5 && variacaoT <= 10)
	{
//	    notificar(this.nome + ": Equalizando Temperatura por 2 turnos.");
//	    this.holdStill = 2;
	    return 2;
	}
	else if (variacaoT > 10 && variacaoT <= 15)
	{
//	    notificar(this.nome + ": Equalizando Temperatura por 3 turnos.");
//	    this.holdStill = 3;
	    return 3;
	}
	else if (variacaoT > 15)
	{
//	    notificar(this.nome + ": Equalizando Temperatura por 4 turnos.");
//	    this.holdStill = 4;
	    return 4;
	}
	else
	{
//	    notificar(this.nome + ": Funcionando normalmente.");
//	    this.holdStill = 0;
	    
	    return 0;
	}
    }

    private float simularTemperatura()
    {
	Random variaTemp = new Random();
	float temp = variaTemp.nextFloat() * 400;

	return temp;
    }

    private float simularPressao()
    {
	Random variaP = new Random();
	float pressao = variaP.nextFloat() * 10;

	return pressao;
    }

    private float verificarTemperatura()
    {
	float variacaoTemp = 0;
	if (temperatura > maxTemp)
	{
	    variacaoTemp = calculo(maxTemp, temperatura);
	}
	else if (temperatura < minTemp)
	{
	    variacaoTemp = calculo(minTemp, pressao);
	}
	return variacaoTemp;
    }

    private float verificarPressao()
    {
	float variacaoP = 0;
	if (pressao > otimoPressao)
	{
	    variacaoP = calculo(otimoPressao, pressao);
	}
	else if (pressao < otimoPressao)
	{
	    variacaoP = calculo(otimoPressao, pressao);
	}
	return variacaoP;
    }

    private float calculo(float valorRef, float valorVar)
    {
	float result = ((valorVar * 100) / valorRef) - 100;

	return result > 0 ? result : -1 * result;
    }

    public void registrarObserver(Observer monitor)
    {
	monitores.add(monitor);
    }

    public void removerObserver(Observer monitor)
    {
	monitores.remove(monitor);
    }

    public void notificar(String status)
    {
	for (Observer m : monitores)
	{
	    m.atualizar(status);
	}
    }
}
